#include "flash.h"

u16 FLASH_BUF[SECTOR_SIZE/2]; //1KByte




//提供给用户的函数
void FLASH_Write(u32 Addr,u16 *pBuff,u16 len)
{
	u32 Sector_Number;  //第几扇区
	u32 Sector_Relative;   //扇区内偏移地址（按16位计算）
	u32 Sector_Remain;     //扇区内剩余地址（按16位计算）
	u32 OffAddr;           //减去0x08000000后的地址
	u16 i;
	
	//判断地址合理性
	if(Addr<FLASH_BASE || Addr>=(FLASH_BASE+1024*FLASH_SIZE))return;
	
	FLASH_Unlock();
	
	OffAddr = Addr - FLASH_BASE;
	Sector_Number = OffAddr/SECTOR_SIZE;
	Sector_Relative = (OffAddr%SECTOR_SIZE)/2;
	Sector_Remain = SECTOR_SIZE/2-Sector_Relative;
	
	//如果一页能够写完
	if(len <= Sector_Remain) Sector_Remain = len;
	
	//写入
	while(1)
	{
		//整页读出
		FLASH_Read(Sector_Number*SECTOR_SIZE+FLASH_BASE,FLASH_BUF,SECTOR_SIZE/2);
		
		for(i=0;i<Sector_Remain;i++)
		{
			if(FLASH_BUF[Sector_Relative+i] != 0xFFFF) break; //需要擦除
		}
		if(i<Sector_Remain) //需要擦除
		{
			FLASH_ErasePage(Sector_Number*SECTOR_SIZE+FLASH_BASE);
			
			//替换数据
			for(i=0;i<Sector_Remain;i++)
			{
				FLASH_BUF[Sector_Relative+i] = pBuff[i];
			}
			
			//写入FLASH
			FLASH_Writ_NoCheck(Sector_Number*SECTOR_SIZE+FLASH_BASE,FLASH_BUF,SECTOR_SIZE/2);	
		}
		else
		{
			FLASH_Writ_NoCheck(Addr,pBuff,Sector_Remain);
		}
		
		if(len == Sector_Remain) break; //写入结束
		else
		{
			Sector_Number++;          //页+1
			Sector_Relative = 0;      //页内偏移0
			pBuff += Sector_Remain;   //更新传入的数组指针
			Addr += Sector_Remain*2;    //写地址偏移
			len -= Sector_Remain;     //更新写长度
			
			if(len>(SECTOR_SIZE/2)) Sector_Remain = SECTOR_SIZE/2;
			else Sector_Remain = len;
		}
	}
	
	FLASH_Lock();
}




//读取一个半字（16位）
u16 FLASH_ReadHalfWord(u32 faddr)
{
	return *(vu16*)faddr; 
}


//读出一段数据（16位）
void FLASH_Read(u32 Addr,u16 *pBuff,u16 len)
{
	u16 i;
	for(i=0;i<len;i++)
	{
		pBuff[i] = FLASH_ReadHalfWord(Addr);
		Addr += 2;
	}
}

#if FLSAH_EN_WRITE //如果使能了写

//不检查的写入
void FLASH_Writ_NoCheck(u32 Addr,u16 *pBuff,u16 len)
{
	u16 i;
	for(i=0;i<len;i++)
	{
		FLASH_ProgramHalfWord(Addr,pBuff[i]);
		Addr += 2;
	}
}



#endif


























